﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AzureDiagMon.Common.Algorithms.FragmentedRanges
{
    public static class FragmentedRangeSectionExtensions
    {
        /// <summary>
        /// Merge overlapping sections
        /// </summary>
        /// <typeparam name="TRangeIndex"></typeparam>
        /// <param name="ranges"></param>
        /// <param name="comparer"></param>
        /// <returns></returns>
        public static IEnumerable<FragmentedRangeSection<TRangeIndex>> Consolidate<TRangeIndex>(this IEnumerable<FragmentedRangeSection<TRangeIndex>> ranges, 
                                                                            Comparer<TRangeIndex> comparer = null)
            where TRangeIndex : IComparable
        {
            if (ranges == null || !ranges.Any())
                yield break;

            if (comparer == null)
                comparer = Comparer<TRangeIndex>.Default;

            var sections = ranges.OrderBy(r => r.StartIndex);
            var firstSection = sections.First();

            TRangeIndex min = firstSection.StartIndex;
            TRangeIndex max = firstSection.EndIndex;

            foreach (var section in sections.Skip(1))
            {
                if (comparer.Compare(section.EndIndex, max) > 0
                 && comparer.Compare(section.StartIndex, max) > 0)
                {
                    yield return new FragmentedRangeSection<TRangeIndex>(min, max);
                    min = section.StartIndex;
                }
                max = comparer.Compare(max, section.EndIndex) > 0 ? max : section.EndIndex;
            }
            yield return new FragmentedRangeSection<TRangeIndex>(min, max);
        }

    }
}
